#pragma once

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include "Log.hpp"
#include "connection.hpp"

const static int buffersize = 512;

// 不应该让HandlerConnection来处理报文
class HandlerConnection
{
public:
    HandlerConnection(hander_t process)
        : _process(process)
    {
    }
    void HandlerRecver(Connection *conn) // conn就是就绪的conn
    {
        // 1. 直接读取
        //LOG(DEBUG, "client 给我发了消息: %d\n", conn->Connectionfd());
        while (true)
        {
            errno = 0;
            char buffer[buffersize];
            ssize_t n = ::recv(conn->Connectionfd(), buffer, sizeof(buffer) - 1, 0);
            if (n > 0)
            {
                buffer[n] = 0; // 数据块
                conn->AppendInbuffer(buffer);
            }
            else
            {
                if (errno == EWOULDBLOCK)
                {
                    break;
                }
                else if (errno == EINTR)
                {
                    continue;
                }
                else
                {
                    conn->_hander_exceptor(conn); // 统一执行异常处理
                    return;
                }
            }
        }
        // 2. 交给业务处理
        // 一定是读取完毕了，我们应该处理数据了
        _process(conn); // 内容分析
    }
    void HandlerSender(Connection *conn)
    {
        while (true)
        {
            errno = 0;
            int n = ::send(conn->Connectionfd(), conn->Outbuffer().c_str(), conn->Outbuffer().size(), 0);
            if (n > 0)
            {
                conn->Discard(n);              // 将发送缓冲区已经send的数据删掉
                if (conn->Outbuffer().empty()) // 没有发送的数据
                    break;
            }
            else if (n == 0)
            {
                break;
            }
            else
            {
                if (errno == EWOULDBLOCK)
                {
                    // 写条件不满足
                    break;
                }
                else if (errno == EINTR)
                {
                    // 中断
                    continue;
                }
                else
                {
                    // 发生错误
                    conn->_hander_exceptor(conn);
                    return;
                }
            }
        }
        // 还有数据没发送完&&写条件不满足
        if (!conn->Outbuffer().empty() && errno == EWOULDBLOCK)
        {
            // 添加写事件关心
            conn->_R->EnableConnectReadWrite(conn->Connectionfd(), true, true);
        }
        else
        {
            conn->_R->EnableConnectReadWrite(conn->Connectionfd(), true, false);
        }
    }
    void HanlderExcepter(Connection *conn)
    {
        conn->_R->DelConnection(conn->Connectionfd());
    }

private:
    hander_t _process;
};